package com.zxx.numberbutton;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * 购物车商品数量、增加和减少控制按钮。
 * 原文：https://github.com/qinci/NumberButton
 *
 * @author zxx on 2019/8/16
 */
public class NumberButton extends LinearLayout implements View.OnClickListener, TextWatcher {

    private int mInventory = Integer.MAX_VALUE;  //库存
    private int mMax = Integer.MAX_VALUE;
    private EditText mCount;
    private OnWarnListener warnListener;


    public NumberButton(Context context) {
        this(context, null);
    }

    public NumberButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public NumberButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        LayoutInflater.from(context).inflate(R.layout.number_layout, this);
        TextView addButton = findViewById(R.id.button_add);
        addButton.setOnClickListener(this);
        TextView subButton = findViewById(R.id.button_sub);
        subButton.setOnClickListener(this);

        mCount = findViewById(R.id.text_count);
        mCount.addTextChangedListener(this);
        mCount.setOnClickListener(this);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.NumberButton);
        boolean editable = array.getBoolean(R.styleable.NumberButton_editable, true);
        int buttonWidth = array.getDimensionPixelSize(R.styleable.NumberButton_buttonWidth, -1);
        int textWidth = array.getDimensionPixelSize(R.styleable.NumberButton_textWidth, -1);
        int textSize = array.getDimensionPixelSize(R.styleable.NumberButton_textSize, -1);
        int textColor = array.getColor(R.styleable.NumberButton_textColor, 0xff000000);
        array.recycle();

        setEditable(editable);
        mCount.setTextColor(textColor);
        subButton.setTextColor(textColor);
        addButton.setTextColor(textColor);

        if (textSize > 0) {
            mCount.setTextSize(textSize);
        }
        if (buttonWidth > 0) {
            LayoutParams textParams = new LayoutParams(buttonWidth, LayoutParams.MATCH_PARENT);
            subButton.setLayoutParams(textParams);
            addButton.setLayoutParams(textParams);
        }
        if (textWidth > 0) {
            LayoutParams textParams = new LayoutParams(textWidth, LayoutParams.MATCH_PARENT);
            mCount.setLayoutParams(textParams);
        }
    }

    //
    public int getNumber() {
        try {
            return Integer.parseInt(mCount.getText().toString());
        } catch (NumberFormatException e) {
        }
        mCount.setText("1");
        return 1;
    }

    private void setEditable(boolean editable) {
        if (editable) {
            mCount.setFocusable(true);
            mCount.setKeyListener(new DigitsKeyListener());
        } else {
            mCount.setFocusable(false);
            mCount.setKeyListener(null);
        }
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onClick(View view) {
        int id = view.getId();
        int count = getNumber();
        switch (id) {
            case R.id.button_sub:
                if (count > 1) {
                    //正常减
                    mCount.setText("" + (count - 1));
                }
                break;
            case R.id.button_add:
                if (count < Math.min(mMax, mInventory)) {
                    //正常添加
                    mCount.setText("" + (count + 1));
                } else if (mInventory < mMax) {
                    //库存不足
                    warningForInventory();
                } else {
                    //超过最大购买数
                    warningForBuyMax();
                }
                break;
            case R.id.text_count:
                mCount.setSelection(mCount.getText().toString().length());
                break;
        }
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        onNumberInput();
    }

    @Override
    public void afterTextChanged(Editable editable) {
    }

    private void onNumberInput() {
        //当前数量
        int count = getNumber();
        if (count <= 0) {
            //手动输入
            mCount.setText("1");
            return;
        }
        int limit = Math.min(mMax, mInventory);
        if (count > limit) {
            //超过了数量
            mCount.setText(limit + "");
            if (mInventory < mMax) {
                //库存不足
                warningForInventory();
            } else {
                //超过最大购买数
                warningForBuyMax();
            }
        }
        mCount.setSelection(mCount.getText().toString().length());
    }


    //超过的库存限制
    private void warningForInventory() {
        if (warnListener != null) {
            warnListener.onWarningForInventory(mInventory);
        }
    }

    //超过的最大购买数限制
    private void warningForBuyMax() {
        if (warnListener != null) {
            warnListener.onWarningForBuyMax(mMax);
        }
    }

    //
    public NumberButton setCurrentNumber(int currentNumber) {
        if (currentNumber < 1) mCount.setText("1");
        mCount.setText("" + Math.min(Math.min(mMax, mInventory), currentNumber));
        return this;
    }

    public int getInventory() {
        return mInventory;
    }

    public NumberButton setInventory(int inventory) {
        this.mInventory = inventory;
        return this;
    }

    public int getMax() {
        return mMax;
    }

    public NumberButton setMax(int mMax) {
        this.mMax = mMax;
        return this;
    }

    public NumberButton setWarnListener(OnWarnListener warnListener) {
        this.warnListener = warnListener;
        return this;
    }

    interface OnWarnListener {
        void onWarningForInventory(int inventory);

        void onWarningForBuyMax(int max);
    }

}
